<?php
//$ipPort = "lovestory-ceshi.dsgame.iqiyi.com:8689";
$ipPort = "192.168.10.10:8282";

$client = stream_socket_client("tcp://".$ipPort.'/');
//stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
//stream_set_blocking($client, false);
stream_socket_sendto($client, "GET / HTTP/1.1\r\n".
    "Host: $ipPort\r\n".
    "Origin: null\r\n".
    "Connection: Upgrade\r\n".
    "Upgrade: websocket\r\n".
    "Sec-WebSocket-Version: 13\r\n".
    "Sec-WebSocket-Key: w4v7O6xFTi36lq3RNcgctw==\r\n\r\n");
//stream_socket_enable_crypto($client, false);
//$data = array('cmd' => 9999);
//stream_socket_sendto($client, hybi10Encode(json_encode($data)));

//stream_set_read_buffer($client, 1024);
while (!feof($client)) {

//    while ($motd = fgets($client)) {
//        echo decode(($motd));
//    }

    stream_socket_sendto($client, hybi10Encode("ggggggggggg"));
    sleep(1);
    $str = stream_socket_recvfrom($client, 1024);

    var_dump(($str));
}
//

//echo $str;


//可用的websocket解码
function decode($received)
{
    $len = $masks = $data = $decoded = null;
    $buffer = $received;
    $len = ord($buffer[1]) & 127;
    if ($len === 126) {
        $masks = substr($buffer, 4, 4);
        $data = substr($buffer, 8);
    } else {
        if ($len === 127) {
            $masks = substr($buffer, 10, 4);
            $data = substr($buffer, 14);
        } else {
            $masks = substr($buffer, 2, 4);
            $data = substr($buffer, 6);
        }
    }
    for ($index = 0; $index < strlen($data); $index++) {
        $decoded .= $data[$index] ^ $masks[$index % 4];
    }

    return $decoded;
}

//可用的websocket掩码
function hybi10Encode($payload, $type = 'text', $masked = true)
{
    $frameHead = array();
    $payloadLength = strlen($payload);

    switch ($type) {
        //文本内容
        case 'text':
            // first byte indicates FIN, Text-Frame (10000001):
            $frameHead[0] = 129;
            break;

        //二进制内容
        case 'binary':
        case 'bin':
            // first byte indicates FIN, Text-Frame (10000010):
            $frameHead[0] = 130;
            break;

        case 'close':
            // first byte indicates FIN, Close Frame(10001000):
            $frameHead[0] = 136;
            break;

        case 'ping':
            // first byte indicates FIN, Ping frame (10001001):
            $frameHead[0] = 137;
            break;

        case 'pong':
            // first byte indicates FIN, Pong frame (10001010):
            $frameHead[0] = 138;
            break;
    }

    // set mask and payload length (using 1, 3 or 9 bytes)
    if ($payloadLength > 65535) {
        $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8);
        $frameHead[1] = ($masked === true) ? 255 : 127;
        for ($i = 0; $i < 8; $i++) {
            $frameHead[$i + 2] = bindec($payloadLengthBin[$i]);
        }
        // most significant bit MUST be 0 (close connection if frame too big)
        if ($frameHead[2] > 127) {
            $this->socket->close();
            return false;
        }
    } elseif ($payloadLength > 125) {
        $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8);
        $frameHead[1] = ($masked === true) ? 254 : 126;
        $frameHead[2] = bindec($payloadLengthBin[0]);
        $frameHead[3] = bindec($payloadLengthBin[1]);
    } else {
        $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength;
    }

    // convert frame-head to string:
    foreach (array_keys($frameHead) as $i) {
        $frameHead[$i] = chr($frameHead[$i]);
    }

    // generate a random mask:
    $mask = array();
    if ($masked === true) {
        for ($i = 0; $i < 4; $i++) {
            $mask[$i] = chr(rand(0, 255));
        }
        $frameHead = array_merge($frameHead, $mask);
    }
    $frame = implode('', $frameHead);
    // append payload to frame:
    for ($i = 0; $i < $payloadLength; $i++) {
        $frame .= $masked ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
    }
    return $frame;
}

//
function hybi10Decode($data)
{
    if (empty($data)) {
        throw new \Exception("没有数据");
        exit;
    }

    $bytes = $data;
    $secondByte = sprintf('%08b', ord($bytes[1]));
    $masked = ($secondByte[0] == '1') ? true : false;
    $dataLength = ($masked === true) ? ord($bytes[1]) & 127 : ord($bytes[1]);
    //服务器不会设置mask
    if ($dataLength === 126) {
        $decodedData = substr($bytes, 4);
    } elseif ($dataLength === 127) {
        $decodedData = substr($bytes, 10);
    } else {
        $decodedData = substr($bytes, 2);
    }
//    exit("len=".$dataLength."\n");
    return $decodedData;
}


function encode($buffer)
{
    $len = strlen($buffer);

    $first_byte = "\x81";

    if ($len <= 125) {
        $encode_buffer = $first_byte . chr($len) . $buffer;
    } else {
        if ($len <= 65535) {
            $encode_buffer = $first_byte . chr(126) . pack("n", $len) . $buffer;
        } else {
            //pack("xxxN", $len)pack函数只处理2的32次方大小的文件，实际上2的32次方已经4G了。
            $encode_buffer = $first_byte . chr(127) . pack("xxxxN", $len) . $buffer;
        }
    }

    return $encode_buffer;
}